/*
Copyright 2011 Mohit Shah
    
This file is part of SoundBlogs.

SoundBlogs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

SoundBlogs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with SoundBlogs.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.application.soundblogs;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.Date;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.osmdroid.ResourceProxy;
import org.osmdroid.api.IGeoPoint;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.ItemizedIconOverlay;
import org.osmdroid.views.overlay.ItemizedOverlayWithFocus;
import org.osmdroid.views.overlay.OverlayItem;

import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

public class BlogMap extends Activity {

	// ===========================================================
	// Constants
	// ===========================================================

	private static final int MENU_ZOOMIN_ID = Menu.FIRST;
	private static final int MENU_ZOOMOUT_ID = MENU_ZOOMIN_ID + 1;
	private static final int VISIT_BLOG_ID = MENU_ZOOMOUT_ID +1;

	// ===========================================================
	// Fields
	// ===========================================================

	private MapView mOsmv;
	private ItemizedOverlayWithFocus<OverlayItem> mMyLocationOverlay;
	private ResourceProxy mResourceProxy;
	private static final String LAT = "lat";
	private static final String LON = "lon";
	private static final String AUDIO_SAMPLE = "sample";
	private static final String AUDIO_SOURCE = "source";
	private double lat,lon;
	private String audio_url;
	private int latE6, lonE6, audio_source, audio_sample;
	private Dialog dialog;
	private String datetime, date, time = null;
	private EditText blog_text;
	private OverlayItem current = null;
	private MediaPlayer mPlayer = null;
	private Button listen_button = null;
	private boolean isPlaying = false;
	private boolean isUploadedAudio = false;
    private AsyncTask<Void,Integer,Void> mUpload, playaudio = null;

	// ===========================================================
	// Constructors
	// ===========================================================
	/** Called when the activity is first created. */
	@Override
	public void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.mytitle);
		mResourceProxy = new ResourceProxyImpl(getApplicationContext());
		Bundle extras = getIntent().getExtras();
		audio_source = extras.getInt(AUDIO_SOURCE);
		audio_sample = extras.getInt(AUDIO_SAMPLE);
		Log.d("BlogPlayer",Integer.toString(audio_source));
		Log.d("BlogPlayer",Integer.toString(audio_sample));
		String audio_url = null;
		lat = extras.getDouble(LAT);
		lon = extras.getDouble(LON);
		latE6 = (int) (lat*(1000000));
		lonE6 = (int) (lon*(1000000));
		final RelativeLayout rl = new RelativeLayout(this);

		this.mOsmv = new MapView(this, 256);		
		this.mOsmv.getController().setCenter(new GeoPoint(latE6,lonE6));
		this.mOsmv.getController().setZoom(15);
		this.mOsmv.getController().animateTo(new GeoPoint(latE6,lonE6));
		rl.addView(this.mOsmv, new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.FILL_PARENT));
		datetime = DateFormat.getDateTimeInstance().format(new Date());
		date = DateFormat.getDateInstance().format(new Date());
		time = DateFormat.getTimeInstance().format(new Date());
		/* Itemized Overlay */
		{
			/* Create a static ItemizedOverlay showing a some Markers on some cities. */
			final ArrayList<OverlayItem> items = new ArrayList<OverlayItem>();
			current = new OverlayItem(datetime, "Current Location", new GeoPoint(latE6,lonE6));
			items.add(current);
			//items.add(new OverlayItem(datetime, "Current Location", new GeoPoint(latE6,lonE6)));
			
			/* OnTapListener for the Markers, shows a simple Toast. */
			this.mMyLocationOverlay = new ItemizedOverlayWithFocus<OverlayItem>(items,
					new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
						@Override
						public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
							dialog = new Dialog(BlogMap.this);
							dialog.setContentView(R.layout.blog_overlay_dialog);
							dialog.setTitle(item.getTitle());
							TextView recent = (TextView) dialog.findViewById(R.id.recent);
							TextView recent1 = (TextView) dialog.findViewById(R.id.recent1);
							TextView recent2 = (TextView) dialog.findViewById(R.id.recent2);
							TextView snippet = (TextView) dialog.findViewById(R.id.snippet);
							blog_text = (EditText) dialog.findViewById(R.id.blog_text);
							listen_button = (Button) dialog.findViewById(R.id.blog_listen);
							listen_button.setOnClickListener(new audio_play());
							Button save_button = (Button) dialog.findViewById(R.id.blog_save);
							save_button.setOnClickListener(new save_info());
							dialog.show();
							return true;							
						}

						@Override
						public boolean onItemLongPress(final int index, final OverlayItem item) {
							Toast.makeText(
									BlogMap.this,
									"Item '" + item.mTitle + "' (index=" + index
											+ ") got long pressed", Toast.LENGTH_LONG).show();
							return false;
						}
					}, mResourceProxy);
			this.mMyLocationOverlay.setFocusItemsOnTap(false);
			//this.mMyLocationOverlay.setFocusedItem(0);

			this.mOsmv.getOverlays().add(this.mMyLocationOverlay);
			final ImageView ivZoomIn = new ImageView(this);
			ivZoomIn.setImageResource(R.drawable.zoom_in);
			/* Create RelativeLayoutParams, that position in in the top right corner. */
			final RelativeLayout.LayoutParams zoominParams = new RelativeLayout.LayoutParams(
					RelativeLayout.LayoutParams.WRAP_CONTENT,
					RelativeLayout.LayoutParams.WRAP_CONTENT);
			zoominParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
			zoominParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
			rl.addView(ivZoomIn, zoominParams);

			ivZoomIn.setOnClickListener(new zoom_in()); 

			/* Create a ImageView with a zoomOut-Icon. */
			final ImageView ivZoomOut = new ImageView(this);
			ivZoomOut.setImageResource(R.drawable.zoom_out);

			/* Create RelativeLayoutParams, that position in in the top left corner. */
			final RelativeLayout.LayoutParams zoomoutParams = new RelativeLayout.LayoutParams(
					RelativeLayout.LayoutParams.WRAP_CONTENT,
					RelativeLayout.LayoutParams.WRAP_CONTENT);
			zoomoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
			zoomoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
			rl.addView(ivZoomOut, zoomoutParams);

			ivZoomOut.setOnClickListener(new zoom_out()); 

		}

		this.setContentView(rl);
	}

	private class zoom_in implements View.OnClickListener{
		@Override
		public void onClick(final View v) {
			BlogMap.this.mOsmv.getController().zoomIn();
		}
	};
	private class zoom_out implements View.OnClickListener {
		@Override
		public void onClick(final View v) {
			BlogMap.this.mOsmv.getController().zoomOut();
		}
	};
	private void uploadAudio(){
		String Tag = new String("UploadAudio");
	    String lineEnd = "\r\n";
	    String twoHyphens = "--";
	    String boundary = "*****";
	    HttpURLConnection conn = null;
	    String file = new String("/sdcard/test.wav");
	    String urlString = "http://soundblogs.org/uploadFile.php";
	    try {
	        // ------------------ CLIENT REQUEST

	        Log.e(Tag, "Inside second Method");

	        FileInputStream fileInputStream = new FileInputStream(new File(
	                file));

	        // open a URL connection to the Servlet

	        URL url = new URL(urlString);

	        // Open a HTTP connection to the URL

	        conn = (HttpURLConnection) url.openConnection();

	        // Allow Inputs
	        conn.setDoInput(true);

	        // Allow Outputs
	        conn.setDoOutput(true);

	        // Don't use a cached copy.
	        conn.setUseCaches(false);

	        // Use a post method.
	        conn.setRequestMethod("POST");

	        conn.setRequestProperty("Connection", "Keep-Alive");

	        conn.setRequestProperty("Content-Type",
	                "multipart/form-data;boundary=" + boundary);

	        DataOutputStream dos = new DataOutputStream(conn.getOutputStream());

	        dos.writeBytes(twoHyphens + boundary + lineEnd);
	        dos
	                .writeBytes("Content-Disposition: post-data; name=fileToUpload;filename="
	                        + file + "" + lineEnd);
	        dos.writeBytes(lineEnd);

	        Log.e(Tag, "Headers are written");

	        // create a buffer of maximum size

	        int bytesAvailable = fileInputStream.available();
	        int maxBufferSize = 1000;
	        // int bufferSize = Math.min(bytesAvailable, maxBufferSize);
	        byte[] buffer = new byte[bytesAvailable];

	        // read file and write it into form...

	        int bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);

	        while (bytesRead > 0) {
	            dos.write(buffer, 0, bytesAvailable);
	            bytesAvailable = fileInputStream.available();
	            bytesAvailable = Math.min(bytesAvailable, maxBufferSize);
	            bytesRead = fileInputStream.read(buffer, 0, bytesAvailable);
	        }

	        // send multipart form data necesssary after file data...

	        dos.writeBytes(lineEnd);
	        dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

	        // close streams
	        Log.e(Tag, "File is written");
	        fileInputStream.close();
	        dos.flush();
	        dos.close();

	    } catch (MalformedURLException ex) {
	        Log.e(Tag, "error: " + ex.getMessage(), ex);
	    }

	    catch (IOException ioe) {
	        Log.e(Tag, "error: " + ioe.getMessage(), ioe);
	    }

	    try {
	        BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	        String line;
	        while ((line = rd.readLine()) != null) {
	            Log.e("Dialoge Box", "Message: " + line);
	        }
	        rd.close();
	        isUploadedAudio = true;

	    } catch (IOException ioex) {
	        Log.e("MediaPlayer", "error: " + ioex.getMessage(), ioex);
	    }
	}
	private void postData() throws JSONException{
		// Create a new HttpClient and Post Header
		HttpClient httpclient = new DefaultHttpClient();
		HttpPost httppost = new HttpPost("http://soundblogs.org/post.php");
		JSONObject json = new JSONObject();

		try {
			// JSON data:
			if(audio_source==0) {
				json.put("source", "test");
			}
			else if(audio_source==1 && audio_sample==1){
				json.put("source","fireworks");
			}
			else if(audio_source==1 && audio_sample==2){
				json.put("source","firealarm");
			}
			else if(audio_source==1 && audio_sample==3){
				json.put("source","traffic");
			}
			json.put("date", date);
			json.put("time", time);
			json.put("latitude", Double.toString(lat));
			json.put("longitude", Double.toString(lon));
			json.put("description", blog_text.getText());
			JSONArray postjson=new JSONArray();
			postjson.put(json);
			Log.d("JSONPost","JSON Array Built");

			// Post the data:
			httppost.setHeader("json",json.toString());
			httppost.getParams().setParameter("jsonpost",postjson);

			// Execute HTTP Post Request
			System.out.print(json);
			HttpResponse response = httpclient.execute(httppost);
			Log.d("JSONPost","JSON Post Executed");

			// for JSON:
			if(response != null)
			{
				InputStream is = response.getEntity().getContent();

				BufferedReader reader = new BufferedReader(new InputStreamReader(is));
				StringBuilder sb = new StringBuilder();

				String line = null;
				try {
					while ((line = reader.readLine()) != null) {
						sb.append(line + "\n");
					}
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					try {
						is.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				Log.d("JSONPost",sb.toString());
			}

		}catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
		} catch (IOException e) {
    		// TODO Auto-generated catch block
    	}
	}
	private void prepareSource(){
		Uri.Builder b = Uri.parse("No Source").buildUpon();
		if(audio_source==0){
        	b = Uri.parse("/sdcard/test.wav").buildUpon();

		}
		else if(audio_source!=0){
	    	Resources res = getResources();
	    	CharSequence[] urls = res.getTextArray(R.array.audio_files);
			b = Uri.parse(urls[audio_sample].toString()).buildUpon();
		}
    		String url = b.build().toString();
    		Log.d("BlogPlayer",url);
    		audio_url = new String(url);
	}
	
	private class audio_play implements View.OnClickListener{
		@Override
		public void onClick(View v){
			if(!isPlaying){
				Toast.makeText(getApplicationContext(), "Playing Audio...", Toast.LENGTH_LONG).show();
				listen_button.setText("       Stop       ");
				playaudio = new PlayAudio().execute();
			}
			else {
				mPlayer.release();
				mPlayer = null;
				listen_button.setText("Play Clip");
				isPlaying = false;
			}
		}
			
	};
    private class PlayAudio extends AsyncTask<Void,Integer,Void> {
    	@Override
    	public Void doInBackground(Void... params){
    		Void ret = null;
			mPlayer = new MediaPlayer();
			try {
				prepareSource();
				mPlayer.setDataSource(audio_url);					
            	mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
				mPlayer.prepare();
				mPlayer.start();
				isPlaying = true;
			}
			catch (IOException e) {
				Log.e("BlogPlayer", "prepare() failed");
			}
    		return ret;
    	}
    }

	private class save_info implements View.OnClickListener{
		@Override
		public void onClick(View v){
			Toast.makeText(getApplicationContext(), "Saving...Please wait for 2-3 minutes before opening Blog", Toast.LENGTH_LONG).show();
			mUpload = new MyUploader().execute();
			dialog.cancel();
		}
	};
	
	private class MyUploader extends AsyncTask<Void,Integer,Void>{
		protected Void doInBackground (Void... params){
			Void ret = null;
			if(audio_source==0) {
				if(!isUploadedAudio) {		
					try {
						postData();
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					uploadAudio();
				}
			}
			else if(audio_source==1) {
				try {
					postData();
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			return ret;
		}
	     protected void onPostExecute(Void result) {
	         Toast.makeText(getApplicationContext(), "Process Completed...Please Visit Your Blog", Toast.LENGTH_LONG).show();
	     }

	}
	@Override
	public boolean onCreateOptionsMenu(final Menu pMenu) {
		pMenu.add(0, MENU_ZOOMIN_ID, Menu.NONE, "ZoomIn");
		pMenu.add(0, MENU_ZOOMOUT_ID, Menu.NONE, "ZoomOut");
		pMenu.add(0, VISIT_BLOG_ID, Menu.NONE, "Visit Blog");
		return true;
	}

	@Override
	public boolean onMenuItemSelected(final int featureId, final MenuItem item) {
		switch (item.getItemId()) {
		case MENU_ZOOMIN_ID:
			this.mOsmv.getController().zoomIn();
			return true;

		case MENU_ZOOMOUT_ID:
			this.mOsmv.getController().zoomOut();
			return true;
		case VISIT_BLOG_ID:
			String url = "http://soundblogs.org/blog.php";
			Intent i = new Intent(Intent.ACTION_VIEW);
			i.setData(Uri.parse(url));
			startActivity(i);
		}
		return false;
	}

	// ===========================================================
	// Methods
	// ===========================================================

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}
